﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

using System.Linq;
using System.Windows.Data;
using System.ComponentModel;
using VocabManager.Command;
using VocabManager.Model;
using System.Collections.Generic;
using VocabManager.View;

namespace VocabManager.ViewModel
{
    public class DeckViewModel : ViewModelBase
    {
        bool _isloaded;
        AppListViewModel _appViewModel;
        private Deck _deck;
        internal Deck Deck
        {
            get
            {
                return _deck;
            }
        }
        
        internal ObservableCollection<ItemViewModel> AllItems { get; set; }
        private VocabManager.DataLayer.ItemRepository _itemRepository;
        CollectionViewSource _collectionViewSource;


        public bool IsNew
        {
            get;
            set;
        }
        public bool IsInEditMode
        {
            get;
            set;
        }

        public ICollectionView CardItems
        {
            get
            {
                return _collectionViewSource.View;
            }

        }
        public ItemViewModel CurrentItem
        {
            get
            {
                return CardItems.CurrentItem as ItemViewModel;
            }
        }
        public DeckViewModel(AppListViewModel appViewModel,VocabManager.DataLayer.ItemRepository itemRepository,Deck deck)
        {
            _appViewModel = appViewModel;
            _itemRepository = itemRepository;
            _deck = deck;

          
        }

        public void LoadItems()
        {
            if (_isloaded)
                return;
            AllItems = new ObservableCollection<ItemViewModel>
                (_itemRepository.GetAllItems(_deck.Id).Select(item => new ItemViewModel(item, this)));
            _collectionViewSource = new CollectionViewSource();
            _collectionViewSource.Source = AllItems;
            CardItems.CurrentChanged += new EventHandler(CardItems_CurrentChanged);
            _isloaded = true;



        }
    
        void CardItems_CurrentChanged(object sender, EventArgs e)
        {
            if (this.CurrentItem != null && !CurrentItem.IsFrontSide)
                CurrentItem.IsFrontSide = true;
            OnPropertyChanged("CurrentItem");
        }

        public string Name
        {
            get
            {
                return _deck.Name;
            }
            set
            {
                if (_deck.Name == value)
                    return;
                _deck.Name = value;
                OnPropertyChanged("Name");
            }
        }
        public string Description
        {
            get
            {
                return _deck.Description;
            }
            set
            {
                if (_deck.Description == value)
                    return;
                _deck.Description = value;
                OnPropertyChanged("Description");
            }
        }
        public int Id
        {
            get
            {
                return _deck.Id;
            }
        }
        public string CreationTime
        {
            get
            {
                return _deck.CreationTime.ToString();
            }
        }






        #region search
        RelayCommand _searchCommand;
        public ICommand SearchCommand
        {
            get
            {
                if (_searchCommand == null)
                {
                    _searchCommand = new RelayCommand(
                        param => this.Search(),
                        param => this.CanSearch()
                        );
                }
                return _searchCommand;
            }
        }

        private bool CanSearch()
        {
            throw new NotImplementedException();
        }

        private object Search()
        {
            throw new NotImplementedException();
        }

        #endregion
        public void SaveItem(ItemViewModel item)
        {
            if(item.IsNew)
                _itemRepository.AddNewItem(item.Item);
            else
                _itemRepository.UpdateItem(item.Item);

        }
        #region Remove
        RelayCommand _removeCurrentCommand;
        public ICommand RemoveCurrentCommand
        {
            get
            {
                if (_removeCurrentCommand == null)
                {
                    _removeCurrentCommand = new RelayCommand(
                        param => this.RemoveCurrent(),
                        param => this.CanRemoveCurrent()
                        );
                }
                return _removeCurrentCommand;
            }
        }

        private void RemoveCurrent()
        {
            RemoveItem(this.CurrentItem);
        }

        private bool CanRemoveCurrent()
        {
            return true;
        }
        public void RemoveItem(ItemViewModel item)
        {
            if (this.CardItems.CurrentItem == item)
                this.CardItems.MoveCurrentToNext();
            this.AllItems.Remove(item);
            if (!item.IsNew)
                _itemRepository.RemoveItem(item.Item);



        }
        #endregion
        #region AddNew
        RelayCommand _addNewCommand;
        public ICommand AddNewCommand
        {
            get
            {
                if (_addNewCommand == null)
                {
                    _addNewCommand = new RelayCommand(
                        param => this.AddNew(),
                        param => this.CanAddNew()
                        );
                }
                return _addNewCommand;
            }
        }

        private bool CanAddNew()
        {

            throw new NotImplementedException();
        }

        private void AddNew()
        {
            Item newCard = Item.CreateNew();
            ItemViewModel itemViewModel = new ItemViewModel(newCard, this);
            
            itemViewModel.IsInEditMode = itemViewModel.IsNew = true;

            AllItems.Add(itemViewModel);
            CardItems.MoveCurrentTo(itemViewModel);

        }
        #endregion
        #region Next
        RelayCommand _nextCommand;
        public ICommand NextCommand
        {
            get
            {
                if (_nextCommand == null)
                {
                    _nextCommand = new RelayCommand(
                        param => this.GoToNext(),
                        param => this.CanNext()
                        );
                }
                return _nextCommand;
            }
        }

        private bool CanNext()
        {
            return true;
        }

        private void GoToNext()
        {
            if (this.CardItems.OfType<ItemViewModel>().Count() > 0)
            {
                this.CardItems.MoveCurrentToNext();
                if (this.CurrentItem == null)
                    this.CardItems.MoveCurrentToFirst();
            }
        }
        #endregion
        #region Perevious
        RelayCommand _previousCommand;
        public ICommand PereviousCommand
        {
            get
            {
                if (_previousCommand == null)
                {
                    _previousCommand = new RelayCommand(
                        param => this.GoToPrevious(),
                        param => this.CanGoToPrevious()
                        );
                }
                return _previousCommand;
            }
        }

        private bool CanGoToPrevious()
        {

            return true;
        
        }

        private void GoToPrevious()
        {
            if (this.CardItems.OfType<ItemViewModel>().Count() > 0)
            {
                this.CardItems.MoveCurrentToPrevious();
                if (this.CurrentItem == null)
                    this.CardItems.MoveCurrentToLast();
            }
            
        }
        #endregion


        #region Cancel
        RelayCommand _cancelEditCommand;
        public ICommand CancelEditCommand
        {
            get
            {
                if (_cancelEditCommand == null)
                {
                    _cancelEditCommand = new RelayCommand(
                        param => this.CancelEdit(),
                        param => this.CanCancelEdit()
                        );
                }
                return _cancelEditCommand;
            }
        }



        private bool CanCancelEdit()
        {
            return IsInEditMode;
        }

        Dictionary<string, object> _tempPropertyValues;

        private void CancelEdit()
        {
            if (IsNew)
                _appViewModel.RemoveCurrentDeckCommand.Execute(null);
            else
            {
               
                this.Name = _tempPropertyValues["Name"] as string;
                this.Description = _tempPropertyValues["Description"] as string;
            }
            this.IsInEditMode = false;
            App.Instance.MainPage.LoadDeckListView();
        }

        #endregion

        #region Save


        RelayCommand _saveCommand;
        public ICommand SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                {
                    _saveCommand = new RelayCommand(
                        param => this.Save(),
                        param => this.CanSave()
                        );
                }
                return _saveCommand;
            }
        }


        private void Save()
        {
            _appViewModel.SaveDeck(this);
         this.IsNew =   this.IsInEditMode = false;

            App.Instance.MainPage.LoadDeckListView();
        }



        private bool CanSave()
        {
            return IsInEditMode;
        }

        #endregion

        #region Edit
        RelayCommand _editCommand;
        public ICommand EditCommand
        {
            get
            {
                if (_editCommand == null)
                {
                    _editCommand = new RelayCommand(
                        param => this.Edit(),
                        param => this.CanEdit()
                        );
                }
                return _editCommand;
            }
        }
        private bool CanEdit()
        {
            return true;
        }

        private void Edit()
        {
            IsInEditMode = true;
            BeginEdit();
            DeckViewEdit editView = new DeckViewEdit();
            editView.DataContext = this;
            App.Instance.MainPage.LoadView(editView);
        }

        void BeginEdit()
        {
            _tempPropertyValues = new Dictionary<string, object>();
            _tempPropertyValues.Add("Name", this.Name);
            _tempPropertyValues.Add("Description", this.Description);

        }
        #endregion

        #region Review
        RelayCommand _reviewCommand;
        public ICommand ReviewCommand
        {
            get
            {
                if (_reviewCommand == null)
                {
                    _reviewCommand = new RelayCommand(
                        param => this.Review(),
                        param => this.CanReview()
                        );
                }
                return _reviewCommand;
            }
        }
        private bool CanReview()
        {
            return true;
        }

        private void Review()
        {
            if (this.CardItems.OfType<ItemViewModel>().Count() != 0)
                this.CardItems.MoveCurrentToFirst();
        }

        #endregion
    }
}
